﻿using System;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace MassIntellect.Drawing.Shapes
{
	public class CurvedRectangle : Shape
	{
		#region Свойства

		private int _DiameterCurveLeftTop;
		public int DiameterCurveLeftTop
		{
			get
			{ return _DiameterCurveLeftTop; }
			set
			{
				if (value != _DiameterCurveLeftTop)
				{
					_DiameterCurveLeftTop = value;
					OnPropertyChanged("DiameterCurveLeftTop");
				}
			}
		}

		private int _DiameterCurveRightTop;
		public int DiameterCurveRightTop
		{
			get
			{ return _DiameterCurveRightTop; }
			set
			{
				if (value != _DiameterCurveRightTop)
				{
					_DiameterCurveRightTop = value;
					OnPropertyChanged("DiameterCurveRightTop");
				}
			}
		}

		private int _DiameterCurveLeftBottom;
		public int DiameterCurveLeftBottom
		{
			get
			{ return _DiameterCurveLeftBottom; }
			set
			{
				if (value != _DiameterCurveLeftBottom)
				{
					_DiameterCurveLeftBottom = value;
					OnPropertyChanged("DiameterCurveLeftBottom");
				}
			}
		}

		private int _DiameterCurveRightBottom;
		public int DiameterCurveRightBottom
		{
			get
			{ return _DiameterCurveRightBottom; }
			set
			{
				if (value != _DiameterCurveRightBottom)
				{
					_DiameterCurveRightBottom = value;
					OnPropertyChanged("DiameterCurveRightBottom");
				}
			}
		}

		public int DiameterCurveAll
		{
			set
			{
				DiameterCurveLeftTop = value;
				DiameterCurveRightTop = value;
				DiameterCurveLeftBottom = value;
				DiameterCurveRightBottom = value;
			}
		}

		public bool IsCurve
		{
			get
			{
				return DiameterCurveLeftTop != 0
				       || DiameterCurveLeftBottom != 0
				       || DiameterCurveRightTop != 0
				       || DiameterCurveRightBottom != 0;
			}
		}

		public override GraphicsPath GraphicsPath
		{
			get
			{
				var grp = new GraphicsPath();

				if (IsCurve)
				{
					int rLeftTop = DiameterCurveLeftTop / 2,
					    rRightTop = DiameterCurveRightTop / 2,
					    rLeftBottom = DiameterCurveLeftBottom / 2,
					    rRightBottom = DiameterCurveRightBottom / 2;

					if (DiameterCurveLeftTop > 0) grp.AddArc(X, Y, DiameterCurveLeftTop, DiameterCurveLeftTop, 180, 90);
					grp.AddLine(X + rLeftTop, Y, X + Width - rRightTop, Y);
					if (DiameterCurveRightTop > 0) grp.AddArc(X + Width - DiameterCurveRightTop, Y, DiameterCurveRightTop, DiameterCurveRightTop, 270, 90);
					grp.AddLine(X + Width, Y + rRightTop, X + Width, Y + Height - rRightBottom);
					if (DiameterCurveRightBottom > 0) grp.AddArc(X + Width - DiameterCurveRightBottom, Y + Height - DiameterCurveRightBottom, DiameterCurveRightBottom, DiameterCurveRightBottom, 0, 90);
					grp.AddLine(X + Width - rRightBottom, Y + Height, X + rLeftBottom, Y + Height);
					if (DiameterCurveLeftBottom > 0) grp.AddArc(X, Y + Height - DiameterCurveLeftBottom, DiameterCurveLeftBottom, DiameterCurveLeftBottom, 90, 90);
					grp.AddLine(X, Y + Height - rLeftBottom, X, Y + rLeftTop);
				}
				else
					grp.AddRectangle(new RectangleF(X, Y, Width, Height));

				return grp;
			}
		}

		#endregion

		#region Методы

		//public override PointF Joint(PointF pnt)
		//{
		//    PointF res = new PointF(), Center = new PointF(X + Width / 2, Y + Height / 2);
		//    if (!JointVectors(X + DiameterCurveLeftTop, Y, Right - DiameterCurveRightTop, Y, Center.X, Center.Y, pnt.X, pnt.Y, out res)
		//        && !JointVectors(X + DiameterCurveLeftBottom, Bottom, X + DiameterCurveRightBottom, Bottom, Center.X, Center.Y, pnt.X, pnt.Y, out res)
		//        && !JointVectors(X, Y + DiameterCurveLeftTop, X, Bottom - DiameterCurveLeftBottom, Center.X, Center.Y, pnt.X, pnt.Y, out res)
		//        && !JointVectors(Right, Y + DiameterCurveRightTop, Right, Bottom - DiameterCurveRightBottom, Center.X, Center.Y, pnt.X, pnt.Y, out res))
		//    {
		//        PointF nr = NormalizeVector(Center.X, Center.Y, pnt.X, pnt.Y);
		//        Direction dir;                
		//    }
		//    return res;
		//}

		public override object Clone()
		{
			var sh = Cloning<CurvedRectangle>();
			sh.DiameterCurveLeftBottom = DiameterCurveLeftBottom;
			sh.DiameterCurveLeftTop = DiameterCurveLeftTop;
			sh.DiameterCurveRightBottom = DiameterCurveRightBottom;
			sh.DiameterCurveRightTop = DiameterCurveRightTop;
			return sh;
		}

		public override bool Contains(PointF pnt)
		{
			var bnd = Bounds;
			int rLeftTop = DiameterCurveLeftTop / 2,
			    rRightTop = DiameterCurveRightTop / 2,
			    rLeftBottom = DiameterCurveLeftBottom / 2,
			    rRightBottom = DiameterCurveRightBottom / 2;
			return bnd.Contains(pnt) && (!IsCurve ||
			                             (
			                             	(rLeftTop == 0 || !new RectangleF(bnd.X, bnd.Y, rLeftTop, rLeftTop).Contains(pnt)
			                             	 || Math.Sqrt(Math.Pow(pnt.X - (bnd.X + rLeftTop), 2) + Math.Pow(pnt.Y - (bnd.Y + rLeftTop), 2)) <= rLeftTop)
			                             	&& (rRightTop == 0 || !new RectangleF(bnd.Right - rRightTop, bnd.Y, rRightTop, rRightTop).Contains(pnt)
			                             	    || Math.Sqrt(Math.Pow(pnt.X - (bnd.Right - rRightTop), 2) + Math.Pow(pnt.Y - (bnd.Y + rRightTop), 2)) <= rRightTop)
			                             	&& (rLeftBottom == 0 || !new RectangleF(bnd.X, bnd.Bottom - rLeftBottom, rLeftBottom, rLeftBottom).Contains(pnt)
			                             	    || Math.Sqrt(Math.Pow(pnt.X - (bnd.X + rLeftBottom), 2) + Math.Pow(pnt.Y - (bnd.Bottom - rLeftBottom), 2)) <= rLeftBottom)
			                             	&& (rRightBottom == 0 || !new RectangleF(bnd.Right - rRightBottom, bnd.Bottom - rRightBottom, rRightBottom, rRightBottom).Contains(pnt)
			                             	    || Math.Sqrt(Math.Pow(pnt.X - (bnd.Right - rRightBottom), 2) + Math.Pow(pnt.Y - (bnd.Bottom - rRightBottom), 2)) <= rRightBottom)
			                             ));
		}

		public override string ToString()
		{
			return string.Format("Скруглённый прямоугольник({0},{1})", X, Y);
		}

		#endregion
	}
}